import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 设置图形风格
sns.set_style("whitegrid")
plt.rcParams['figure.dpi'] = 300
plt.rcParams['font.size'] = 10
plt.rcParams['font.sans-serif'] = ['SimHei']

# 数据采样，只加载10%的数据
data = pd.read_csv('UserBehavior.csv', header=None,
                   names=['user_id', 'item_id', 'category_id', 'behavior_type', 'timestamp'],
                   skiprows=lambda x: x % 10 != 0)

# 数据基本检查
print("数据前5行：")
print(data.head())
print("\n数据基本信息：")
print(data.info())
print("\n缺失值情况：")
print(data.isnull().sum())

# 转换时间戳为日期时间格式
data['datetime'] = pd.to_datetime(data['timestamp'], unit='s')
data['date'] = data['datetime'].dt.date
data['hour'] = data['datetime'].dt.hour

# 检查并删除重复值
data.drop_duplicates(inplace=True)

# 重新排列列顺序
data = data[['user_id', 'item_id', 'category_id', 'behavior_type', 'date', 'hour', 'datetime']]

# 保存清洗后的数据
data.to_csv('cleaned_UserBehavior_sample.csv', index=False)

# 用户行为类型分布
behavior_dist = data['behavior_type'].value_counts().sort_index()
print("\n用户行为类型分布：")
print(behavior_dist)

# 可视化行为类型分布
plt.figure(figsize=(10, 6))
sns.barplot(x=behavior_dist.index, y=behavior_dist.values, palette='viridis')
plt.title('用户行为类型分布')
plt.xlabel('行为类型')
plt.ylabel('次数')
plt.savefig('用户行为类型分布.png')
plt.show()

# 用户行为转化漏斗
funnel = data.groupby('behavior_type')['user_id'].nunique().sort_index()
conversion_rate = funnel / funnel['pv'] * 100

print("\n用户行为转化漏斗：")
print(funnel)
print("\n转化率：")
print(conversion_rate)

# 可视化转化漏斗
plt.figure(figsize=(10, 6))
sns.barplot(x=funnel.index, y=funnel.values, palette='rocket')
plt.title('用户行为转化漏斗')
plt.xlabel('行为类型')
plt.ylabel('唯一用户数')
plt.savefig('用户行为转化漏斗.png')  # 保存图片
plt.show()

# 用户活跃度分析
user_activity = data.groupby('user_id')['behavior_type'].count().reset_index()
user_activity.columns = ['user_id', 'total_actions']

# 查看用户活跃度分布
plt.figure(figsize=(10, 6))
sns.histplot(user_activity['total_actions'], bins=50, kde=True, color='mediumblue')
plt.title('用户活跃度分布')
plt.xlabel('总行为次数')
plt.ylabel('用户数')
plt.savefig('用户活跃度分布.png')
plt.show()

# 时间维度分析 - 每日行为趋势
daily_behavior = data.groupby(['date', 'behavior_type']).size().unstack(fill_value=0)
daily_behavior.columns = ['click', 'add_to_cart', 'purchase', 'favorite']

# 可视化每日行为趋势
plt.figure(figsize=(15, 8))
for behavior in ['click', 'add_to_cart', 'purchase', 'favorite']:
    plt.plot(daily_behavior.index, daily_behavior[behavior], label=behavior)

plt.title('每日用户行为趋势')
plt.xlabel('日期')
plt.ylabel('次数')
plt.legend()
plt.xticks(rotation=45)
plt.savefig('每日用户行为趋势.png')
plt.show()

# 时间维度分析 - 每小时行为分布
hourly_behavior = data.groupby(['hour', 'behavior_type']).size().unstack(fill_value=0)
hourly_behavior.columns = ['click', 'add_to_cart', 'purchase', 'favorite']

# 可视化每小时行为分布
plt.figure(figsize=(15, 8))
for behavior in ['click', 'add_to_cart', 'purchase', 'favorite']:
    plt.plot(hourly_behavior.index, hourly_behavior[behavior], label=behavior)

plt.title('每小时用户行为分布')
plt.xlabel('小时')
plt.ylabel('次数')
plt.legend()
plt.savefig('每小时用户行为分布.png')
plt.show()

# 商品维度分析
item_behavior = data.groupby(['item_id', 'behavior_type']).size().unstack(fill_value=0)
item_behavior.columns = ['click', 'add_to_cart', 'purchase', 'favorite']

# 按购买次数排序
top_items = item_behavior.sort_values(by='purchase', ascending=False).head(20)

# 可视化热门商品
plt.figure(figsize=(15, 8))
sns.barplot(x='purchase', y=top_items.index.astype(str), data=top_items, palette='magma')
plt.title('购买量最高的20个商品')
plt.xlabel('购买次数')
plt.ylabel('商品ID')
plt.savefig('购买量最高的20个商品.png')
plt.show()

# 用户行为路径分析
# 按用户和时间排序数据
user_sequence = data.sort_values(['user_id', 'datetime']).groupby('user_id')['behavior_type'].apply(list).reset_index()
user_sequence.columns = ['user_id', 'behavior_sequence']

# 查看前5个用户的行文序列
print("\n前5个用户的行文序列：")
print(user_sequence.head())

# RFM模型分析
# 计算每个用户的最近一次购买时间、购买频率和购买金额（假设购买行为代表金额）
purchase_data = data[data['behavior_type'] == 'purchase']
if not purchase_data.empty:
    rfm_data = purchase_data.groupby('user_id').agg(
        recency=('datetime', lambda x: (purchase_data['datetime'].max() - x.max()).days),
        frequency=('user_id', 'count'),
        monetary=('item_id', 'count')
    ).reset_index()

    # 检查 recency 列是否有空值或无效值
    rfm_data = rfm_data.dropna(subset=['recency'])

    # 对RFM指标进行分层
    for col in ['recency', 'frequency', 'monetary']:
        # 确保值唯一且有效
        unique_values = rfm_data[col].unique()
        if len(unique_values) >= 3:
            rfm_data[col + '_score'] = pd.qcut(rfm_data[col], 3, labels=[1, 2, 3], duplicates='drop')
        else:
            # 如果唯一值不足3个，直接赋值
            rfm_data[col + '_score'] = 1

    # 计算综合得分
    rfm_data['rfm_score'] = rfm_data['recency_score'] + rfm_data['frequency_score'] + rfm_data['monetary_score']

    # 按综合得分分群
    rfm_data['cluster'] = pd.qcut(rfm_data['rfm_score'], 3, labels=['低价值', '中价值', '高价值'], duplicates='drop')

    # 可视化RFM分群
    plt.figure(figsize=(10, 6))
    sns.countplot(x='cluster', data=rfm_data, palette='Set2')
    plt.title('RFM用户分群')
    plt.xlabel('用户群')
    plt.ylabel('用户数')
    plt.savefig('RFM用户分群.png')
    plt.show()
else:
    print("没有购买行为数据，无法进行RFM分析。")